package simulation;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.*;
import java.util.ArrayList;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.plaf.SliderUI;

import behaviour.Explorer;

import pacman.Ghost;
import pacman.GhostRunner;
import pacman.Pacman;
import sensors.virtualSensors.VirtualInfraredSensor;
import sensors.virtualSensors.VirtualLightSensor;
import sensors.virtualSensors.VirtualUltrasonicSensor;

import maze.Barcode;
import maze.Location;
import maze.Maze;




public class GuiTest extends Panel  {
	private final int FPS = 30;
	private boolean updateLight = false;//boolean to double the time to redraw lightsensor values
	
	private Simulator simulator; // The simulation that calculates the values.
	
	 BufferedImage  sector;
	 BufferedImage  pacman;
	 BufferedImage  background;
	 BufferedImage map;
	 BufferedImage colormap;
	 BufferedImage robot;
	 BufferedImage blackScreen;
	 BufferedImage robotrotated;
	 BufferedImage fog;
	 
	
	 BufferedImage MazePanel= new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
	 BufferedImage MazePanelBuffer = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
	 boolean drawColormap = false;
	 Maze maze;
	 private int selectedghost = 1;
	 private ArrayList<Ghost> ghosts;
	 
	 int toDraw = 0; // 0 = real map, 1 = map from robot 1, 2 for robot 2 etc...
	 int[] light1 = new int[50];
	 int[] light2 = new int[50];
	 int[] light3 = new int[50];
	 int[] light4 = new int[50];
	 boolean initiated = false;
	 boolean drawing = false;
	 boolean imagesloaded = false;
	 private int angle = 0;
	private double x;
	private double y;
	private double xOffset = 0;
	private double yOffset = 0;
	 JButton Rightbutton = new JButton("X Right");
	 JButton Leftbutton = new JButton("X Left");
	 JButton Upbutton = new JButton("Y Down");
	 JButton Downbutton = new JButton("Y UP");
	 Timer timer;
	 ColorMap color;
	private char[][] walls = { //index with maze[-y][x]
			{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
			{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,2,1,2,2,1,2,1,2,1,2,2,1,2,2,2,1},
			{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,2,2,2,1,1,2,1,1,2,2,1,2,2,2,1,2,1,2,1},
			{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1},
			{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,2,1,1,2,1,2,1,1,2,1},
			{1,2,1,2,2,1,2,1,2,1,2,1,1,1,2,1,1,2,1,2,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1,1},
			{1,2,1,2,2,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,2,1,2,2,1,2,1,2,1,2,1,2,2,1,1,2,1,2,2,1},
			{1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,2,1,2,1,2,2,1,2,2,1,2,1,2,1,1},
			{1,2,1,2,1,1,1,2,1,2,1,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,2,2,1,2,1,2,2,2,2,2,1},
			{1,2,1,2,2,2,1,2,1,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1},
			{1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,2,1,2,1},
			{1,1,2,1,1,1,2,1,1,2,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,2,1,1,1,2,2,1,2,1,2,1,2,1,2,1},
			{1,2,1,2,2,1,2,2,1,2,2,1,2,1,2,1,2,1,2,2,2,1,1,2,1,1,2,1,2,2,2,1,1,2,1,2,1,2,1,2,1},
			{1,1,2,1,1,2,2,1,1,2,2,1,2,1,2,1,2,1,2,1,1,1,2,2,2,1,2,2,1,2,1,2,1,2,1,1,2,1,1,2,1},
			{1,2,2,1,2,2,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,1,2,1,2,2,2,1,1},
			{1,2,2,2,1,2,1,1,2,1,2,2,1,2,2,1,2,1,2,2,2,1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,2,1,1,2,1},
			{1,1,1,2,1,1,2,1,2,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,2,2,1,1,2,1,2,1,1,2,1,2,1,2,2,1},
			{1,2,2,1,1,2,2,2,1,2,1,2,1,2,1,1,2,1,1,2,1,1,2,1,2,1,2,2,1,2,1,2,2,1,2,2,1,2,1,2,1},
			{1,1,2,2,1,2,1,1,1,1,2,2,2,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1},
			{1,2,2,1,1,1,2,1,2,1,2,1,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,2,2,2,1,1,2,1,1,2,2,2,1,2,1},
			{1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,1,1,2,1,1}
			};
			
	
	
	
	
	public GuiTest(final Simulator simulator){
	//public GuiTest(){
		this.simulator = simulator;
		if( simulator.getMaze() != null){
		walls = simulator.getMaze().getRawData();
		maze = simulator.getMaze();
		}
		if(simulator.getColorMap() != null)
			color = simulator.getColorMap();
		
		ghosts = new ArrayList<Ghost>();
		Set<Ghost> robs = simulator.getGhostLocations().keySet();
		for (Ghost ghost : robs) {
			if(!ghosts.contains(ghost)){
				ghosts.add(ghost);
			}
		}
		
		//random values to test graph
		/*for (int i = 0; i < 100; i++) {
			light1[i] = (int) ((Math.random() * 20));
			if (Math.random()<0.5)
				light1[i] = -light1[i];
		}
		for (int i = 0; i < 100; i++) {
			light2[i] = (int) ((Math.random() * 20));
			if (Math.random()<0.5)
				light2[i] = -light2[i];
		}
		for (int i = 0; i < 100; i++) {
			light3[i] = (int) ((Math.random() * 20));
			if (Math.random()<0.5)
				light3[i] = -light3[i];
		}
		for (int i = 0; i < 100; i++) {
			light4[i] = (int) ((Math.random() * 20));
			if (Math.random()<0.5)
				light4[i] = -light4[i];
		}*/
		//end random values.
		
		
		setLayout(new BorderLayout());
		//mouselistener to select robots
		this.addMouseListener(new MouseListener(){

			@Override
			public void mouseClicked(MouseEvent click) {
				//System.out.println(click.getX()+ "," + click.getY());
				if (click.getX() >6*getWidth()/8){
					if (click.getY()<getHeight()/4 && click.getY() > 0){
						selectedghost=0;
						toDraw =1;}
					else if (click.getY()<getHeight()/4*2 && click.getY() > getHeight()/4){
						selectedghost=1;
						toDraw =2;}
					else if (click.getY()<getHeight()/4*3 && click.getY() > getHeight()/4*2){
						selectedghost=2;
						toDraw =3;}
					else if (click.getY()<getHeight() && click.getY() >getHeight()/4*3){
						selectedghost=3;
						toDraw =4;}
					
					
				}else toDraw =0;
				
				
			}

			@Override
			public void mouseEntered(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseExited(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mousePressed(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseReleased(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}});
		//FPS is frames per second to draw to screen;
		timer = new Timer(1000/FPS, new ActionListener(){

		
			
			//timer to set when to draw the screen and update values
			@Override
			public void actionPerformed(ActionEvent arg0) {
				
				draw();
				Set<Ghost> robs = simulator.getGhostLocations().keySet();
				for (Ghost ghost : robs) {
					if(!ghosts.contains(ghost)){
						ghosts.add(ghost);
					}
				}
				
				
			
				
				//random values for lightsensor, normaly for each robot get this from sensor
				
							
					try{
						AddLightValue(light1,  (ghosts.get(0).getLightSensor().readValue()-127)*20/127);
					}catch(Exception e){
						AddLightValue(light1,  0);
					};		
				
					try{
						AddLightValue(light2,  (ghosts.get(1).getLightSensor().readValue()-127)*20/127);
					}catch(Exception e){
						AddLightValue(light2,  0);
					};	
					
					try{
						AddLightValue(light3,  (ghosts.get(2).getLightSensor().readValue()-127)*20/127);
					}catch(Exception e){
						AddLightValue(light3,  0);
					};	
					
					try{
						AddLightValue(light4,  (ghosts.get(3).getLightSensor().readValue()-127)*20/127);
					}catch(Exception e){
						AddLightValue(light4,  0);
					};	
			
				
			
				timer.restart();
				
			}});

		timer.start();
		this.setFocusable(true);
		this.requestFocus();
		 KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
	        manager.addKeyEventDispatcher(new MyDispatcher());
		loadImages();
		this.setVisible(true);
		//pacman location for testing
		x = 12;
		y = 12;
		this.setPreferredSize(new Dimension(800,600));
		this.validate();
		
		 JFrame jf = new JFrame("Simulation");
		  this.setFocusable(true);
		  this.requestFocusInWindow();
		   jf.setFocusable(true);
		   jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	  
		   jf.getContentPane().add(this);
		   jf.getContentPane().setPreferredSize(new Dimension(800,600));	 
		   jf.validate();
		   jf.pack();
		   jf.setVisible(true);
		
		initiated = true;
		
	}
	
	
	/**
	 * add a new value to the history of lightvalues to draw
	 * @param original
	 * 			|Original Array of values
	 * @param newvalue
	 * 			|New Value to add to the end
	 */
	private void AddLightValue(int[] original,int newvalue){
		for (int i = 0; i < original.length-1; i++) {
			original[i] = original[i+1];
		}
		original[original.length-1] = newvalue;
		//return original;
	}
	
	/**
	 * adds to the position of pacman for tests
	 * @param xpos
	 * @param ypos
	 */
	public void setPosition(double xpos, double ypos){
	x += xpos;
	y += ypos;
	}
	
	/**
	 * Loads the images used
	 */
	public void loadImages(){
		 try {                
	          sector = ImageIO.read(new File("simulation/sector_rand.png"));
	          pacman = ImageIO.read(new File("simulation/pacman.png"));
	          background = ImageIO.read(new File("simulation/wood.jpg"));
	          robot = ImageIO.read(new File("simulation/robot.png"));
	          blackScreen = ImageIO.read(new File("simulation/DataScreenRobot.png"));
	          robotrotated =  ImageIO.read(new File("simulation/robot.png"));
	          fog = ImageIO.read(new File("simulation/fogofwar.png"));
	          
	       } catch (IOException ex) {
	    	   try {                
	 	          sector = ImageIO.read(new File("..\\PenOGuiFiles\\sector_rand.png"));
	 	          pacman = ImageIO.read(new File("..\\PenOGuiFiles\\pacman.png"));
	 	          background = ImageIO.read(new File("..\\PenOGuiFiles\\wood.jpg"));
	 	          robot = ImageIO.read(new File("..\\PenOGuiFiles\\robot.png"));
	 	          blackScreen = ImageIO.read(new File("..\\PenOGuiFiles\\DataScreenRobot.png"));
	 	          robotrotated =  ImageIO.read(new File("..\\PenOGuiFiles\\robot.png"));
	 	       } catch (IOException e) {
	 	    	  try {
					sector = ImageIO.read(new File("../PenOTiles/sector_rand.png"));
					pacman = ImageIO.read(new File("../PenOTiles/pacman.png"));
			          background = ImageIO.read(new File("../PenOTiles/wood.jpg"));
			          robot = ImageIO.read(new File("../PenOTiles/robot.png"));
			          blackScreen = ImageIO.read(new File("../PenOTiles/DataScreenRobot.png"));
			          robotrotated =  ImageIO.read(new File("../PenOTiles/robot.png"));
			          fog = ImageIO.read(new File("../PenOTiles/fogofwar.png"));
				} catch (IOException e1) {
					System.out.println("file not found in GuiTest");
				}
		          
	 	            
	 	       }
	       }
	       imagesloaded = true;
	}
	
	
	private void drawColorMap(Graphics map){
		
		BufferedImage[][] tiles = color.getTileMap();
		
		for (int i = 0; i < tiles.length; i++) {
			for (int j = 0; j < tiles[0].length; j++) {
				map.drawImage(tiles[j][tiles.length-1-i],j*40,i*40,null);//colormap.getHeight()-((i+1)*40),null);
			}
		}
		map.dispose();
	}
	
	/**
	 * Draws the whole map with walls to an image to avoid overhead work
	 * @param map
	 */
	private void drawMazeImage(BufferedImage m,char[][] mazeToDraw,boolean drawBarcodes){
		
		Graphics map = m.getGraphics();
		BufferedImage fogofwar = new BufferedImage(m.getWidth(),m.getHeight(),BufferedImage.TYPE_INT_ARGB );
		Graphics fogfwar = fogofwar.getGraphics();
		
		//draw sectors
		
		for (int i = 0; i < mazeToDraw.length-1; i++) {
			  for (int j = 0; j < (mazeToDraw[1].length)/2; j++) {
				double YStartPos = (i)*40;
				double XStartPos = (j)*40;	
			  map.drawImage(sector,(int)XStartPos ,(int)YStartPos,null);
			  }
		}
		
		
		
		//draw barcodes
		if (drawBarcodes){
		for (Barcode code : maze.getBarcodes()) {
			addBarcode(code.getX(), code.getY(), code.getCode(), code.getDirection());
		}
		}
		
		
		
		
		// draw walls
		map.setColor(new Color(90,43,0));
		int YStart = 0;//(int)(-yOff*40);
		int XStart = 0;//(int)(-xOff*40);
		
		for (int i = 0; i < mazeToDraw.length; i++) {
			for (int h = 0; h < mazeToDraw[1].length; h+=2) {
				if(mazeToDraw[(int) (i)][(int) (h)] == 1){
				
					map.drawLine(h/2*40-1-XStart, (i-1)*40-YStart, (h/2)*40-1-XStart, (i+1-1)*40-YStart);
					map.drawLine(h/2*40-XStart, (i-1)*40-YStart, (h/2)*40-XStart, (i+1-1)*40-YStart);
					map.drawLine(h/2*40+1-XStart, (i-1)*40-YStart, (h/2)*40+1-XStart, (i+1-1)*40-YStart);
				}
				if(mazeToDraw[(int) (i)][(int) (h)] == 0){
					map.drawImage(fog,(((h/2)*40)-20),((i-1)*40-YStart),null);
					
				}
				
							}  
			for (int v = 0; v < mazeToDraw[1].length-1; v+=2) {
				
				if(mazeToDraw[i][v+1] == 1){
			
					map.drawLine((v/2)*40, (i+1-1)*40-1, (v/2+1)*40, (i+1-1)*40-1);
				map.drawLine((v/2)*40, (i+1-1)*40, (v/2+1)*40, (i+1-1)*40);
					map.drawLine((v/2)*40, (i+1-1)*40+1, (v/2+1)*40, (i+1-1)*40+1);
				}
				if(mazeToDraw[i][v+1] == 0){
					map.drawImage(fog,(((v/2)*40)),(((i)*40)-20),null);
					
				}
			}  
		}
		fogfwar.dispose();
		//map.drawImage(fogofwar, 0,0, null);
		//map.drawImage(scale(scale(fogofwar,1/8),8), 0,0, null);
		map.dispose();
	}
	
	/**
	 * Draws the whole map with walls to an image to avoid overhead work
	 * @param map
	 */
	private BufferedImage drawGhostMazeImage(BufferedImage m,Maze ghostMaze,boolean drawBarcodes){
		int maxX = ghostMaze.getMaxX()+1;
		int maxY = ghostMaze.getMaxY()+1;
		int minX = ghostMaze.getMinX();
		int minY = ghostMaze.getMinY();
		int minXWrap = ghostMaze.getMinXWrap();
		int minYWrap = ghostMaze.getMinYWrap();
		int size = ghostMaze.getSize();
		
		//the image to draw the whole maze onto, even the white space
		 
		BufferedImage temp  = new BufferedImage(40*(int)(ghostMaze.getRawData()[0].length/2)+40, 40*ghostMaze.getRawData().length, BufferedImage.TYPE_INT_ARGB);

		BufferedImage fogofwar  = new BufferedImage(40*(int)(ghostMaze.getRawData()[0].length/2)+40, 40*ghostMaze.getRawData().length, BufferedImage.TYPE_INT_ARGB);
		Graphics2D map = (Graphics2D)temp.getGraphics();
		map.setStroke(new BasicStroke(2f));
		Graphics fogfwar = fogofwar.getGraphics();
	//	System.out.println(m.getWidth() + "," + m.getHeight());
		//draw sectors
		
		char[][] mazeToDraw = ghostMaze.getRawData();
		for (int i = 0; i < size+1; i++) {
			  for (int j = 0; j < size+1; j++) {
				double YStartPos = (i)*40;
				double XStartPos = (j)*40;	
			  map.drawImage(sector,(int)XStartPos ,(int)YStartPos,null);
			  }
		}
		
		
		
		//draw barcodes
		if (drawBarcodes){
		for (Barcode code : maze.getBarcodes()) {
			addBarcode(code.getX(), code.getY(), code.getCode(), code.getDirection());
		}
		}
		
		// draw walls and fog
		map.setColor(new Color(90,43,0));
		int YStart = 0;
		int XStart = 0;
		boolean xskipped = false;
		char[][] data = mazeToDraw;
		
		//draw walls and fog on top row
		for(int x = 0; x<(2*size+1); x++) {
			int yy=data.length-1;
			if(!xskipped && !(((x-1)/2)<maxX)) {
				XStart +=40;
				xskipped = true;
			}
			if(data[yy][x]==1) {
				if(x%2!=0) {
					if(((x-1)/2)<maxX){
						map.drawLine(XStart, YStart, XStart+40, YStart);
						XStart+=40;
					}
				}
				else {
					if(((x-1)/2)<maxX){
						;
					}else{
						map.drawLine(XStart, YStart, XStart+40, YStart);
						XStart+=40;
					}
				}
			} else if(data[yy][x]==0) {;
				if(x%2!=0) {
					if(((x-1)/2)<maxX){
						fogfwar.drawImage(fog,XStart,YStart-20,null);
						XStart+=40;
					}
				}
				else {
					if(((x-1)/2)<maxX){
						;
					}else{
						fogfwar.drawImage(fog,XStart,YStart-20,null);
						XStart+=40;
					}
				}
			} else {
				if(x%2!=0) {
					if(((x-1)/2)<maxX){
						XStart+=40;
					}
				} else {
					if(!(((x-1)/2)<maxX)){
						XStart+=40;
					}
				}
			}
		}
		XStart=0;
		YStart=40;
		xskipped = false;
		
		
		//draw all the other walls and fog
		for(int y = 0; y<size+1; y++) {
			for(int x = 0; x<(2*size+1); x++) {
				if(!xskipped && !(((x-1)/2)<maxX)) {
					XStart +=40;
					xskipped = true;
				}
				if(data[y][x]==1) {
					if(x%2!=0) {
						if(((x-1)/2)<maxX){
							map.drawLine(XStart, YStart, XStart+40, YStart);
							XStart+=40;
						}else{
							map.drawLine(XStart, YStart, XStart, YStart-40);
						}	
						//out+= (((x-1)/2)<=maxx)?"_":"|";
					}
					else {
						if(((x-1)/2)<maxX){
							map.drawLine(XStart, YStart, XStart, YStart-40);
						}else{
							map.drawLine(XStart, YStart, XStart+40, YStart);
							XStart+=40;
						}
						//out+=(((x-1)/2)<=maxx)?"|":"_";
					}
				} else if(data[y][x]==0) {;
					if(x%2!=0) {
						if(((x-1)/2)<maxX){
							fogfwar.drawImage(fog,XStart,YStart-20,null);
							XStart+=40;
						}else{
							fogfwar.drawImage(fog,XStart-20,YStart-40,null);
						}
						
						//out+= (((x-1)/2)<=maxx)?"_":"|";
					}
					else {
						if(((x-1)/2)<maxX){
							fogfwar.drawImage(fog,XStart-20,YStart-40,null);
						}else{
							fogfwar.drawImage(fog,XStart,YStart-20,null);
							XStart+=40;
						}
						//out+=(((x-1)/2)<=maxx)?"|":"_";
					}
				} else {
					if(x%2!=0) {
						if(((x-1)/2)<maxX){
							XStart+=40;
						//out+= (((x-1)/2)<=maxx)?"_":"|";
						}
					} else {
						if(!(((x-1)/2)<maxX)){
							XStart+=40;
						}
						//out+=(((x-1)/2)<=maxx)?"|":"_";
					}
				}
			}
			YStart+=40;
			XStart=0;
			xskipped = false;
		}
		YStart = 40;
		XStart = temp.getWidth();
		//draw the right column
		for(int y = 0; y<size+1; y++) {
			if(data[y][0]==1) {
				map.drawLine(XStart, YStart, XStart, YStart-40);
			} else if(data[y][0]==0) {;
				fogfwar.drawImage(fog,XStart-20,YStart-40,null);
			}
			YStart+=40;
		}
		
		double x = (ghosts.get(toDraw-1).getLocation().x/40);
		double y = (ghosts.get(toDraw-1).getLocation().y/40);
		
			//x = Math.abs(x%(data.length-1));
			x = positivemodulo(x,size+1);
		
			y = positivemodulo(y,size+1);
			y = size+1 - y;
			
		
			
		
		int angle = ghosts.get(toDraw-1).getRotation();
		
	
			BufferedImage rotatedbot = scale(rotate(robot,angle),0.75);
			map.drawImage(rotatedbot,(int)((x)*40)-rotatedbot.getWidth()/2,(int)((y)*40)-rotatedbot.getHeight()/2,null);
			map.drawString("Ghost-"+ toDraw,(int)((x)*40)-20,(int)((y)*40)-20);
		
		fogfwar.dispose();
		//map.drawImage(fogofwar, 0,0, null);
		//map.drawImage(scale(scale(fogofwar,1/8),8), 0,0, null);
		map.drawImage(fogofwar, 0, 0, null);
		map.dispose();
		BufferedImage temp2  = new BufferedImage((maxX-minX)*40, (maxY-minY)*40, BufferedImage.TYPE_INT_ARGB);
		Graphics gr = temp2.getGraphics();
		
		
		
		int d_width = temp2.getWidth();
		int d_height = temp2.getHeight();
		int d_xborder = -minX*40;
		int d_yborder = maxY*40;
		
		int s_width = temp.getWidth();
		int s_height = temp.getHeight();
		int s_xmax = maxX*40;
		int s_ymax = s_height-maxY*40;
		int s_xminwrap = s_width+minX*40;
		int s_yminwrap = -minY*40;
		
		//x-y-
		gr.drawImage(temp, 0, d_yborder, d_xborder, d_height, s_xminwrap, 0, s_width, s_yminwrap, null);
		//x+y+
		gr.drawImage(temp, d_xborder, 0, d_width, d_yborder, 0, s_ymax ,s_xmax, s_height, null);
		//x-y+
		gr.drawImage(temp, 0, 0, d_xborder, d_yborder, s_xminwrap, s_ymax, s_width, s_height, null);
		//x+y-
		gr.drawImage(temp, d_xborder, d_yborder, d_width, d_height, 0, 0, s_xmax, s_yminwrap, null);
		gr.dispose();
		
		
		gr = m.getGraphics();
		gr.setColor(new Color(50,50,50));
		gr.drawImage(temp2, 0, 0, null);
		gr.fillRect(temp2.getWidth(), 0, m.getWidth(), m.getHeight());
		gr.fillRect(0, temp2.getHeight(), m.getWidth(), m.getHeight());
		gr.dispose();
		return m;
	}
	
	
	
	public void addBarcode(int xPos, int yPos, String BC, int direction){
		
		int x = xPos;
		int y = walls.length-2-yPos;
		
		char[] code = new char[BC.length()];
		for (int i = 0; i < code.length; i++) {
			code[i] = BC.charAt(i);
		}
		if (map == null){
			map = new BufferedImage(40*walls.length, 40*walls[0].length/2, BufferedImage.TYPE_INT_ARGB);
			drawMazeImage(map,walls,true);
			
			
		}
		Graphics gr = map.getGraphics();
		
		if(direction ==1)
			drawBarcode(gr,x,y,code,true);
		else
			drawBarcode(gr,x,y,code,false);
		
		gr.dispose();
	}
	
	/**
	 * draw method to paint to an image in memory in stead of to the screen
	 */
	private void draw(){
		if (!drawing){
			drawing = true;
			drawMazeToBuffer();
			
			repaint();
			drawing = false;
			
		}
		
	}


	
	
	/**
	 * the drawing code 
	 */
	private void drawMazeToBuffer() {
		MazePanelBuffer = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
		Graphics2D buffer = (Graphics2D) MazePanelBuffer.getGraphics();
		buffer.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
		buffer.drawImage(background,0,0,300,300,0,0,350,350,null);
		buffer.drawImage(background,300,0,600,300,0,0,350,350,null);
		buffer.drawImage(background,0,300,300,600,0,0,350,350,null);
		buffer.drawImage(background,300,300,600,600,0,0,350,350,null);
		
		
		
		
		if (toDraw == 0){
			
		drawMainMap(buffer);	
		}else{
		
			
			
			
		Maze maze = ghosts.get(toDraw-1).getMaze();
				
		int width = maze.getSize();		
		  
		//System.out.println("maze size: " + maze.getRawData().length + " x " +  maze.getRawData()[0].length);
		BufferedImage botMap = new BufferedImage(40*width,40*width, BufferedImage.TYPE_INT_ARGB);  
		botMap = drawGhostMazeImage(botMap,maze,false);
			
		
			
		buffer.drawImage(botMap, 0, 0, 600, 600,null);// (int)(0 + 40*xOffset), (int)(0+40*yOffset), 600+(int)(40*xOffset), 600+(int)(40*yOffset), null);
		
		
		}
//		if (map != null){
//			Graphics mpg = map.getGraphics();
//			mpg.setColor(new Color(255,255,0));
//			int xx = (int)((simulator.getGhostLocations().get(ghosts.get(0)).x));
//			int yx = (int)((simulator.getGhostLocations().get(ghosts.get(0)).y));
//			yx = (walls.length-1)*40 - yx;
//			mpg.drawLine(xx+2, yx+2, xx+3, yx+3);
//			mpg.setColor(new Color(0,0,255));
//			xx = (int)((simulator.getGhostLocations().get(ghosts.get(1)).x));
//			yx = (int)((simulator.getGhostLocations().get(ghosts.get(1)).y));
//			yx = (walls.length-1)*40 - yx;
//			mpg.drawLine(xx-1, yx+1, xx-2, yx+2);
//			mpg.setColor(new Color(0,80,0));
//			xx = (int)((simulator.getGhostLocations().get(ghosts.get(2)).x));
//			yx = (int)((simulator.getGhostLocations().get(ghosts.get(2)).y));
//			yx = (walls.length-1)*40 - yx;
//			mpg.drawLine(xx+1, yx-1, xx+2, yx-2);
//			mpg.setColor(new Color(255,0,0));
//			xx = (int)((simulator.getGhostLocations().get(ghosts.get(3)).x));
//			yx = (int)((simulator.getGhostLocations().get(ghosts.get(3)).y));
//			yx = (walls.length-1)*40 - yx;
//			mpg.drawLine(xx-2, yx-2, xx-3, yx-3);
//			mpg.dispose();
//			//System.out.println("draw trail");
//			}
		//draw the panels background for the data screens
		drawPanels(buffer);
	
		//draw the values of the data, to be switched with real data from the simulator tommorow
		drawData(buffer);
		
		//draw the graphs of the lightsensor
		drawGraphs(buffer);
		
		
		buffer.dispose();
		MazePanel = MazePanelBuffer;
	}


	private void drawGraphs(Graphics2D buffer) {
		buffer.setColor(new Color(255,128,0));
		for (int i = 1; i < light1.length; i++) {
			buffer.drawLine(599 + (4*i) ,120-light1[i-1],600 + (4*i),120-light1[i]);
			buffer.drawLine(599 + (4*i) ,270-light2[i-1],600 + (4*i),270-light2[i]);
			buffer.drawLine(599 + (4*i) ,420-light3[i-1],600 + (4*i),420-light3[i]);
			buffer.drawLine(599 + (4*i) ,570-light4[i-1],600 + (4*i),570-light4[i]);
		}
	}


	private void drawData(Graphics2D buffer) {
		for (int i = 0; i < 4; i++) {
			try{
			buffer.setColor(new Color(255,128,0));
			
			buffer.drawString("UltraSonic: " + ghosts.get(i).getUltrasonicSensor().getDistance(),605,40 + i*150);
			buffer.drawString("IR: " + simulator.SimulateInfraredSensor(ghosts.get(i)),605,60 + i*150);
			buffer.drawString("Light: "+ simulator.SimulateLightSensor(ghosts.get(i)),605,80 + i*150);
			buffer.drawString("Name: Ghost-"+ (i+1),605,20 + i*150);
			buffer.setColor(new Color(1f,0.5f,0f,0.6f));
			buffer.drawLine(600, 120 + i*150, 800, 120+ i*150);
			buffer.drawLine(600, 140 + i*150, 800, 140+ i*150);
			buffer.drawLine(600, 100 + i*150, 800, 100+ i*150);
			}catch(Exception e){
				buffer.setColor(new Color(255,128,0));
				buffer.drawString("Name: Not connected"+ (i+1),605,20 + i*150);
				buffer.drawString("UltraSonic: ",605,40 + i*150);
				buffer.drawString("IR: NA",605,60 + i*150);
				buffer.drawString("Light: NA",605,80 + i*150);
				buffer.setColor(new Color(1f,0.5f,0f,0.6f));
				buffer.drawLine(600, 120 + i*150, 800, 120+ i*150);
				buffer.drawLine(600, 140 + i*150, 800, 140+ i*150);
				buffer.drawLine(600, 100 + i*150, 800, 100+ i*150);
			}
		}
	}


	private void drawPanels(Graphics2D buffer) {
		buffer.drawImage(blackScreen,600,0,800,150,0,0,blackScreen.getWidth(),blackScreen.getHeight(),null);
		buffer.drawImage(blackScreen,600,150,800,300,0,0,blackScreen.getWidth(),blackScreen.getHeight(),null);
		buffer.drawImage(blackScreen,600,300,800,450,0,0,blackScreen.getWidth(),blackScreen.getHeight(),null);
		buffer.drawImage(blackScreen,600,450,800,600,0,0,blackScreen.getWidth(),blackScreen.getHeight(),null);
		buffer.setColor(new Color(255,128,0));
	}


	private void drawMainMap(Graphics2D buffer) {
		buffer.drawImage(map, 0, 0, 600, 600, (int)(0 + 40*xOffset), (int)(0+40*yOffset), 600+(int)(40*xOffset), 600+(int)(40*yOffset), null);
		
		if (drawColormap){
			
			buffer.drawImage(colormap, 0, 0, 600, 600,(int)(0 + 40*xOffset), (int)(0+40*yOffset), 600+(int)(40*xOffset), 600+(int)(40*yOffset), null);	
			//buffer.drawImage(color.getTileMap()[0][0],0,0,null);
		}
		
		buffer.setColor(new Color(54,125,217));
		//map = new BufferedImage(40*walls.length, 40*walls[0].length/2, BufferedImage.TYPE_INT_ARGB);
		//buffer.drawImage(rotate(robot,angle),(int)((2-xOffset)*40),(int)((5-yOffset)*40),null);
		//buffer.drawString("Ghost-"+ 1,(int)((2-xOffset)*40),(int)((5-yOffset)*40));
		
		//draw the ghosts in the simulator
		int nr = 1;
		try{
		for (Ghost bot :ghosts) {
			double x = (simulator.getGhostLocations().get(bot).x/40);
			double y = (simulator.getGhostLocations().get(bot).y/40);
			int angle = simulator.getGhostRotations().get(bot);
			if (!((int)((x-xOffset)*40)>=600)){
				y = walls.length-1 - y;
				BufferedImage rotatedbot = scale(rotate(robot,angle),0.75);
				buffer.drawImage(rotatedbot,(int)((x-xOffset)*40)-rotatedbot.getWidth()/2,(int)((y-yOffset)*40)-rotatedbot.getHeight()/2,null);
				buffer.drawString("Ghost-"+ nr,(int)((x-xOffset)*40)-20,(int)((y-yOffset)*40)-20);
			}
			nr++;
		}
		}catch(Exception e){};
		
		
		//draw pacman at (x,y)
		try{
		x = simulator.getPacman().getLocation().x/40;
		y = simulator.getPacman().getLocation().y/40;
		}catch(Exception e){};
		if (!((int)((x-xOffset)*40)>=600)){
			
			y = walls.length-1 - y;
		  buffer.drawImage(pacman,(int)((x-xOffset)*40)-20,(int)((y-yOffset)*40)-20,(int)((x-xOffset)*40) +40-20,(int)((y-yOffset)*40)+40-20,0,0,pacman.getWidth(),pacman.getHeight(),null);
		}
	}
	
	@Override
	public void update(Graphics g){
	       paint(g);
	}
	
	@Override
	public void paint(Graphics g) {
		
		if(initiated){
		if(map == null){
			map = new BufferedImage(40*walls.length, 40*walls[0].length/2, BufferedImage.TYPE_INT_ARGB);
			drawMazeImage(map,walls,true);
			draw();
			}
		if(colormap == null){
			if (color != null){
			colormap = new BufferedImage(40*color.getTileMap().length, 40*color.getTileMap()[0].length, BufferedImage.TYPE_INT_RGB);
			drawColorMap(colormap.getGraphics());
			draw();
			
			}
		}
		
		g.drawImage(MazePanel,0,0,getWidth(),getHeight(),null);
		}
		//g.drawImage(map, 0, 0, 600, 600, (int)(0 + 40*xOffset), (int)(0+40*yOffset), 600+(int)(40*xOffset), 600+(int)(40*yOffset), null);
		//drawBarcode example
		//int i = 5;
		//int j = 6;
		//char[] code = {0,1,1,0,1,0,1,1};
		//drawBarcode(g, i, j, code, true);
		//drawBarcode(g, 12, 2, code, false);
		  
		//drawpacman
		 
		
	//	Graphics2D bot = (Graphics2D) robot.getGraphics();
		//bot.rotate(1.2, robot.getWidth(), robot.getHeight());
		
		//g.drawImage(robotrotated,120,120,null);
		//bot.dispose();
		//if (!((int)((x-xOffset)*40)>=600-40))
		//  g.drawImage(pacman,(int)((x-xOffset)*40),(int)((y-yOffset)*40),(int)((x-xOffset)*40) +40,(int)((y-yOffset)*40)+40,0,0,pacman.getWidth(),pacman.getHeight(),null);
	
	}


	
	/**
	 * Draws a barcode at a given position on an image, draws from left to right or up to down.
	 * @param g
	 * 			|The graphics to paint on
	 * @param x
	 * 			|The X position of the tile where to draw the barcode
	 * @param y
	 * 			|The Y position of the tile where to draw the barcode
	 * @param code
	 * 			|The actual barcode to draw
	 * @param hor
	 * 			|Boolean to indicate if the code is horizontal or vertical
	 */
	private void drawBarcode(Graphics g,int x, int y, char[] code,boolean hor){
		
		if (hor){
			for (int i = 0; i < 2*code.length; i+=2) {
				
				if (code[i/2] == '0')
					g.setColor(new Color(0,0,0));
				else
					g.setColor(new Color(255,255,255));
				
				
			g.drawLine(x*40, (y*40)+code.length+ 3 + i, (x+1)*40 , (y*40)+code.length+3 + i);
			g.drawLine(x*40, (y*40)+code.length+3 + i+1, (x+1)*40 , (y*40)+code.length+3 + i+1);	
			}
			
			
		}else{
			for (int i = 0; i < 2*code.length; i+=2) {
				if (code[i/2] == '0')
					g.setColor(new Color(0,0,0));
				else
					g.setColor(new Color(255,255,255));
				
				
			g.drawLine(x*40+code.length + i+3, (y*40), (x)*40+code.length + i +3, ((y+1)*40));
			g.drawLine(x*40+code.length + i+1+3, (y*40), (x)*40 +code.length + i+1+3, ((y+1)*40));	
			}
		}
	}
	
	
	
	   public static void main(String[] args) {
		  char[][] walls = { //index with maze[-y][x]
					{2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2}, 
					{1,1,2,1,2,1,2,2,2,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,2,1,2,2,1,2,1,2,1,2,2,1,2,2,2,1},
					{1,2,2,1,2,1,2,1,1,1,2,1,2,2,1,1,2,1,2,1,2,1,2,2,2,1,1,2,1,1,2,2,1,2,2,2,1,2,1,2,1},
					{1,2,1,2,1,1,2,2,2,1,2,1,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1},
					{1,2,1,1,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,2,1,1,2,1,2,1,1,2,1},
					{1,2,1,2,2,1,2,1,2,1,2,1,1,1,2,1,1,2,1,2,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1,1},
					{1,2,1,2,2,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,2,1,2,2,1,2,1,2,1,2,1,2,2,1,1,2,1,2,2,1},
					{1,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,2,1,2,1,2,2,1,2,2,1,2,1,2,1,1},
					{1,2,1,2,1,1,1,2,1,2,1,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,2,2,2,1,2,1,2,2,2,2,2,1},
					{1,2,1,2,2,2,1,2,1,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1},
					{1,2,1,2,1,2,1,2,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,2,1,2,1},
					{1,1,2,1,1,1,2,1,1,2,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,2,1,1,1,2,2,1,2,1,2,1,2,1,2,1},
					{1,2,1,2,2,1,2,2,1,2,2,1,2,1,2,1,2,1,2,2,2,1,1,2,1,1,2,1,2,2,2,1,1,2,1,2,1,2,1,2,1},
					{1,1,2,1,1,2,2,1,1,2,2,1,2,1,2,1,2,1,2,1,1,1,2,2,2,1,2,2,1,2,1,2,1,2,1,1,2,1,1,2,1},
					{1,2,2,1,2,2,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2,1,1,2,1,2,2,2,1,1},
					{1,2,2,2,1,2,1,1,2,1,2,2,1,2,2,1,2,1,2,2,2,1,2,1,2,1,2,1,1,2,1,2,2,1,2,1,2,1,1,2,1},
					{1,1,1,2,1,1,2,1,2,2,1,2,1,2,1,2,2,1,2,2,1,1,2,1,2,2,2,1,1,2,1,2,1,1,2,1,2,1,2,2,1},
					{1,2,2,1,1,2,2,2,1,2,1,2,1,2,1,1,2,1,1,2,1,1,2,1,2,1,2,2,1,2,1,2,2,1,2,2,1,2,1,2,1},
					{1,1,2,2,1,2,1,1,1,1,2,2,2,2,1,2,1,2,1,2,1,2,2,1,2,1,2,1,1,2,1,2,1,2,1,2,1,2,1,2,1},
					{1,2,2,1,1,1,2,1,2,1,2,1,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,2,2,2,1,1,2,1,1,2,2,2,1,2,1},
					{1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,1,1,2,1,2,1,2,1,1,1,2,1,1}
					};
		  Maze maze = new Maze(walls);
		  ColorMap map = new ColorMap();
		 	 maze.addBarcode(10, 15, "01101001", 0);
		 maze.addBarcode(4, 12, "01111000", 1);
		  map.setupMap(maze, walls.length-1,walls.length-1);
		
	
		/*  Ghost ghost = new Ghost(new Location(140,340), 0);
		  Ghost ghost2 = new Ghost(new Location(460,780), 0);
		  Ghost ghost3 = new Ghost(new Location(140,260), 90);
		  Ghost ghost4 = new Ghost(new Location(460,420), -90);*/
		  Ghost ghost = new Ghost(new Location(20,20), 0,"jan", null);
		  Ghost ghost2 = new Ghost(new Location(20,20), 0, "jef", null);
		  Ghost ghost3 = new Ghost(new Location(20,20), 0, "jonas", null);
		  Ghost ghost4 = new Ghost(new Location(20,20), 0, "jos", null);
		  Simulator simulation = new Simulator(maze,map);
		  simulation.addGhost(ghost, new Location(140,340),0);
		  simulation.addGhost(ghost2, new Location(460,780),0);
		  simulation.addGhost(ghost3, new Location(140,260),90);
		  simulation.addGhost(ghost4, new Location(460,420),-90);
		  ghost.setSimulator(simulation);
		  ghost2.setSimulator(simulation);
		  ghost3.setSimulator(simulation);
		  ghost4.setSimulator(simulation);
		  ghost.strategy=new Explorer(ghost.getMaze());
		  ghost2.strategy=new Explorer(ghost2.getMaze());
		  ghost3.strategy=new Explorer(ghost3.getMaze());
		  ghost4.strategy=new Explorer(ghost4.getMaze());
		  simulation.speed = 1500;
		  Pacman pacman = new Pacman(new Location(420,440));
		  simulation.setPacman(pacman);
		  GuiTest gui = new GuiTest(simulation);
		// gui.addBarcode(10, 15, "01101001", 0);
		 Thread t1 = new Thread(new GhostRunner(ghost));
		 Thread t2 = new Thread(new GhostRunner(ghost2));
		 Thread t3 = new Thread(new GhostRunner(ghost3));
		 Thread t4 = new Thread(new GhostRunner(ghost4));
		 t1.start();
		 t2.start();
		 t3.start();
		 t4.start();
		  
	    }

	   /**
	    * Rotates an image at a certain angle in degrees
	    * @param img
	    * 			|The Image to rotate
	    * @param angle
	    * 			|The angle to rotate, counterclockwise
	    * @return
	    * 			|A copy of the image rotated;
	    */
	   public static BufferedImage rotate(BufferedImage img, int angle) {  
	       angle = - angle;
		   int w = img.getWidth();  
	        int h = img.getHeight();  
	        BufferedImage dimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);  
	        Graphics2D g = dimg.createGraphics();  
	       g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
	        g.rotate(Math.toRadians(angle), w/2, h/2);  
	        
	        g.drawImage(img, null, 0, 0);  
	        return dimg;  
	    }  	   

	   public static BufferedImage scale(BufferedImage img, double factor) {  
	       
		   int w = (int) (img.getWidth()*factor);  
	        int h = (int) (img.getHeight()*factor);  
	        BufferedImage dimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);  
	        Graphics2D g = dimg.createGraphics();  
	       g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
	        g.scale(factor, factor);
	        
	        g.drawImage(img, null, 0, 0);  
	        return dimg;  
	    }  
	   
	   
	   private double positivemodulo(double val, double mod) {
			mod = Math.abs(mod); //no negative modulo allowed
			mod = (mod==0)?1:mod; //no zero modulo either
			while(val<0) val+= mod; //increase val until we're sure it's positive
			return val%mod;
		}


	

	
	
	   private class MyDispatcher implements KeyEventDispatcher {
	        @Override
	        public boolean dispatchKeyEvent(KeyEvent e) {
	        	
	            if (e.getID() == KeyEvent.KEY_PRESSED) {
	            	int keyCode = e.getKeyCode();
	            	
            	    switch( keyCode ) { 
            	        case KeyEvent.VK_Z:
            	        	setPosition(0, -0.1);
            	        	//draw();
            	            break;
            	        case KeyEvent.VK_Q:
            	        	setPosition(-0.1, 0);
            	        	//draw();
            	            break;
            	        case KeyEvent.VK_D:
            	        	setPosition(0.1, 0);
            	        	//draw();
            	            break;
            	        case KeyEvent.VK_S:
            	        	setPosition(0, +0.1);
            	        	//draw();
            	            break;
            	        case KeyEvent.VK_ENTER:
            	        drawColormap = !drawColormap;
            	       
            	        break;
            	        case KeyEvent.VK_NUMPAD5:
                	        
                	       
						try {
							simulator.SimulateTravel(ghosts.get(selectedghost), -100);
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
                	        break;
            	        case KeyEvent.VK_NUMPAD8:
                	        
						try {
							simulator.SimulateTravel(ghosts.get(selectedghost), 100);
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
            	            break;
            	       
            	    }
	            } else if (e.getID() == KeyEvent.KEY_RELEASED) {
	            	
	            	 int keyCode = e.getKeyCode();
	            	    switch( keyCode ) { 
	            	        case KeyEvent.VK_UP:
	            	        	//if (yOffset > 0){
	            	            	  yOffset -=1;//}
	            	        	//draw();
	            	            break;
	            	        case KeyEvent.VK_DOWN:
	            	        	//if (yOffset < (walls.length) - 16){
	            	            	  yOffset +=1;//}
	            	        
	            	        	//draw();
	            	            break;
	            	        case KeyEvent.VK_LEFT:
	            	        	//if (xOffset >0 ){
	            	            	  xOffset -=1;//}
	            	         
	            	        	//draw();
	            	            break;
	            	        case KeyEvent.VK_RIGHT :
	            	        	//if (xOffset < (walls[0].length/2) - 15){
	            	            	  xOffset +=1;//}
	            	        
	            	          	//draw();
	            	            break;
	            	        case KeyEvent.VK_NUMPAD4:
	            	        	
	            	        	
	                	        
	                	        	simulator.SimulateRotation(ghosts.get(selectedghost), 10);
	    							
	                	       
	            	            break;
	            	        case KeyEvent.VK_NUMPAD6:
	                	        
	            	        	
	            	        	simulator.SimulateRotation(ghosts.get(selectedghost), -10);
	            	        
	            	            break;
	            	     }
	            } 
	            return false;
	        }
	    }




	

	
}
